<?php
// 防止恶意调用
if (!defined('IN_TG')) {
    exit('Access decline');
}

/**
 * email_filter()将邮箱用户名部分中间字符转为*
 * @param string $_string 要过滤的email
 * @return string 返回邮箱用户名部分中间字符转为*的新邮箱字符串
 */
function email_filter($_string) {
    if (!$_string) {
        return '';
    }
    if (is_string($_string)) {
        $tokens = explode('@', $_string);
        if (count($tokens) != 2) {
            return '';
        }
        list($email_name, $email_suffix) = $tokens;
        $emaillen = strlen($email_name)/2;
        $txtlen = ceil($emaillen);
        $starlen = floor($emaillen);
        $new_email = substr($email_name, 0, $txtlen).str_repeat('*', $starlen).'@'. $email_suffix;
        return $new_email;
    } else {
        return '';
    }
}

/**
 * mobile_filter()将手机号中间4位转为*
 * @param string $_string 要过滤的手机号
 * @return string 返回手机号4-7位转为4个*的新字符串
 */
function mobile_filter($_string) {
    if (!$_string) {
        return '';
    }
    if (is_string($_string)) {
        return substr($_string, 0, 3) . '****' . substr($_string, -4);
    } else {
        return '';
    }
}

/**
 * chk_mobile 验证手机号是否正确
 * @param string $mobile 要验证的手机号
 * @return bool 返回 true 或 false
 */
function chk_mobile($mobile) {
    if (preg_match("/^1[3456789]\d{9}$/", $mobile)) {
        return true;
    } else {
        return false;
    }
}



/**
 * rn_change_br() 替换指定符号为HTML换行标记：<br />。换行符\n，回车符\r，windows下enter是 \r\n; linux/unix下是\n; mac下是\r
 * @param string $_string 要过滤的字符串
 */
function rn_change_br($_string) {
    $replace_str = str_replace(array("\r\n", "\r", "\n"), "<br />", $_string);
    return $replace_str;
}

/**
 * rn_change_none() 替换换行符\n，回车符\r，windows下enter是 \r\n; linux/unix下是\n; mac下是\r
 * @param string $_string 要过滤的字符串
 */
function rn_change_none($_string) {
    $replace_str = str_replace(array("\r\n", "\r", "\n"), "", $_string);
    return $replace_str;
}



/**
 * gen_cov_arr 将z_arr_gen生成的数组文件《 "1" => "添加" 》改为《 "id":1, "name":"添加" 》形式。并在开始位置添加《 {"id": 0, "name":"请选择"} 》
 * @param array $arr_source 数组名，存在数组时，返回转换后的新Json格式字符串
 * @return string 存在返回键值，不存在返回 '' 空
 */
function gen_cov_arr($arr_source) {
    $new_arr = '';
    if (is_array($arr_source)) {
        $new_arr = '{"id": 0, "name":"请选择"}';
        foreach ($arr_source as $key => $value) {
            $new_arr .= ',{"id":' . $key . ', "name":"' . $value . '"}';
        }
        return $new_arr;
    } else {
        return ''; // 没有找到数组，或不是数组
    }
}


/**
 * arr_compare 检查2个数组键名 键值 是否完全相同
 * @param array $arr1 要比较的第1个数组
 * @param array $arr2 要比较的第2个数组
 * @return boolean 数组键名及键值相同返回true，任意不同返回false 
 */
function arr_compare($arr1, $arr2) {
    if (is_array($arr1) && is_array($arr2)) {
        if (array_diff_assoc($arr1, $arr2) || array_diff_assoc($arr2, $arr1)) {
            return false; // 比较两个数组，有任意差集的就是数组不同。
        } else {
            return true;  // 反复比较后都为空，数据相同
        }
    } else {
        return false;; // 1个不是数组，或2个都不是数组
    }
}


/**
 * get_arr_val 检查键名$arr_key是在数组$arr_source中否存，存在返回键值，不存在返回-
 * @param string|int $arr_key 键名为:数值或字符串
 * @param array $arr_source 数组名
 * @return string 存在返回键值，不存在返回-
 */
function get_arr_val($arr_key, $arr_source) {
    if (is_array($arr_source)) {
        if (array_key_exists($arr_key, $arr_source)) {
            return $arr_source[$arr_key]; // 存在时返回键值
        } else {
            return ''; // 在数组中不存在键名
        }
    } else {
        return ''; // 没有找到数组，或不是数组
    }
}

/**
 * get_arr_key 检查键值$arr_val是在数组$arr_source中否存，存在返回键名，不存在返回0
 * @param string|int $arr_val 键值为:数值或字符串
 * @param array $arr_source 数组名
 * @return string 存在返回键名，不存在返回0
 */
function get_arr_key($arr_val, $arr_source) {
    if (is_array($arr_source)) {
        $result = array_keys($arr_source, $arr_val);
        // echo $result;
        if (count($result)) {
            return $result[0]; // 找到键值，但是是数组
        } else {
            return 0; // 没有找到键值对应数组
        }
    } else {
        return 0; // 没有找到数组，或不是数组
    }
}

/**
 * get_arr_Imgs 查询内容中所有图片的网址，并以数组返回
 * @param string $content 要查询的内容
 * @param string $order 返回类型
 * @return array 返回数组列表
 */
function get_arr_Imgs($content, $order = 'ALL') {
    /** $pattern = "/<img.*?src=[\'|\"](.*?(?:[\.gif|\.jpg]))[\'|\"].*?[\/]?>/"; */
    // 正则语句：以<img开始 + 任意字符 + src= + ' 或 " + 括号中是(任意字符，这里就是网址) 第一个括号写作$match[1] + ' 或 " + 任意字符 + / 可有可无 + > 。  最后 i 表示不区分大小写
    $pattern = "/<img.*? src=[\'|\"](.*?)[\'|\"].*?[\/]?>/i";
    // 执行一个全局正则表达式匹配
    preg_match_all($pattern, $content, $match);
    // 判断有没有获取到网址
    if (isset($match[1]) && !empty($match[1])) {
        if ($order === 'ALL') {
            // 返回网址
            return $match[1];
        }
        if (is_numeric($order) && isset($match[1][$order])) {
            // 返回网址中的第$order个子字符串
            return $match[1][$order];
        }
    }
    return '';
}

/**
 * _get_suspend 正则匹配参数名 及 参数值，匹配时：终止程序（用于$_GET）
 * @param string $key 要匹配的参数名
 * @param string $value 要匹配的参数值
 */
function _get_suspend($key, $value) {
    $val_filter = "'|\\b(alert|confirm|prompt)\\b|<[^>]*?>|^\\+\/v(8|9)|\\b(and|or)\\b.+?(>|<|=|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?(VALUES|VALUE)|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
    $param_filter = "'|\\b(alert|confirm|prompt|get|post|form|insert|update|value|delete|drop|carate)\\b|<[^>]*?>|\\b(and|or)\\b.+?(>|<|=|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?(VALUES|VALUE)|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
    $value = arr_val_foreach($value);
    // 按正则匹配:值
    if (preg_match("/" . $val_filter . "/is", $value, $match) == 1) {
        print_r($match);
        exit('提交带有非法值');
    }
    // 按正则匹配:参数名
    if (preg_match("/" . $param_filter . "/is", $key, $match) == 1) {
        print_r($match);
        exit('提交带有非法参数名');
    }
}

/**
 * arr_val_foreach 将数组中所有值val 连接成一个字符串
 * @param string|array $arr 数组或字符串
 * @return string 返回数组值连接的字符串
 */
function arr_val_foreach($arr) {
    static $str;
    // 如果是字符串，直接返回原数据
    if (!is_array($arr)) {
        return $arr;
    }
    // 数组或嵌套数组，循环获取值 再组成新的一维数值数组。
    foreach ($arr as $key => $val) {
        if (is_array($val)) {
            arr_val_foreach($val);
        } else {
            $str[] = $val;
        }
    }
    // 把数组值组合为一个字符串返回
    return implode($str);
}

/**
 * _cont_filter 替换内容中的敏感文字（post的参数名 及 值）
 * @param string $str 原文章文字
 * @return string 替换后的新文字
 */
function _cont_filter($key, $value) {
    // 按正则匹配:参数名，检查$key如果匹配，就：终止程序
    $param_filter = "'|\\b(alert|confirm|prompt|get|post|form|insert|update|value|delete|drop|carate|and|or|like|script|exec|select|union|set)\\b|<[^>]*?>|<\\s*script\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?(VALUES|VALUE)|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
    // 次数只对比参数名，如果匹配就终止
    if (preg_match("/" . $param_filter . "/is", $key, $match) == 1) {
        print_r($match);
        exit('提交带有非法参数名');
    }
    // 开始检查$value，匹配上的按规则替换，不终止
    $str = $value;
    // <script>...</script> 改为文本
    $pattern = "/<script(\s*.*?)>(.*?)<\s*\/script\s*>/is";
    $replacement = "&lt;script\${1}&gt;\${2}&lt;/script&gt;";
    $str = preg_replace($pattern, $replacement, $str);
    // javascript
    $pattern = "/\bjavascript\b/is";
    $replacement = "&#106avascript";
    $str = preg_replace($pattern, $replacement, $str);
    // jscript:  : = &colon; = &#58; | &#106=j
    $pattern = "/\bjscript\b:/is";
    $replacement = "&#106script&#58;";
    $str = preg_replace($pattern, $replacement, $str);
    // js:   : = &colon; = &#58;
    $pattern = "/\bjs\b:/is";
    $replacement = "&#106;s&#58;";
    $str = preg_replace($pattern, $replacement, $str);
    // about:  : = &colon; = &#58;
    $pattern = "/\babout\b:/is";
    $replacement = "about&#58;";
    $str = preg_replace($pattern, $replacement, $str);
    // file:  : = &colon; = &#58;
    $pattern = "/\bfile\b:/is";
    $replacement = "&file&#58;";
    $str = preg_replace($pattern, $replacement, $str);
    // document.cookie   . = &period; = &#46;
    $pattern = "/\bdocument\b\s*\.\s*\b(cookie|URL|title|activeElement|body|createElement\(.*?\)|documentElement|domain|embeds|forms|getElementsByClassName\(.*?\)|getElementById\(.*?\)|getElementsByName\(.*?\)|getElementsByTagName\(.*?\)|links|querySelector\(.*?\)|querySelectorAll\(.*?\)|readyState|referrer||images)\b/is";
    $replacement = "document&#46;\${1}";
    $str = preg_replace($pattern, $replacement, $str);
    // vbscript:  : = &colon; = &#58;
    $pattern = "/\bvbscript\b:/is";
    $replacement = "&#118bscript&#58;";
    $str = preg_replace($pattern, $replacement, $str);
    // on(moused|mouseu|mouseo|mousem|exit|error|click|keys)
    $pattern = "/on(moused|mouseu|mouseo|mousem|exit|error|click|keys)/is";
    $replacement = "&#111n\${1}";
    $str = preg_replace($pattern, $replacement, $str);
    // <link href=> 改为文本
    $pattern = "/<link(\s*.*?\bhref\b\s*=\s*.*?)>/is";
    $replacement = "&lt;link\${1}&gt;";
    $str = preg_replace($pattern, $replacement, $str);
    // <!-- html注释 -->  &lt;=<   &excl;=!   &#45;=-  &gt;=>
    $pattern = "/<!\s*-\s*-\s*(.*?)\s*-\s*->/is";
    $replacement = "&lt;&excl;&#45;&#45; \${1} &#45;&#45;&gt;";
    $str = preg_replace($pattern, $replacement, $str);
    // return string
    return $str;
}
/**
 * _html_encode html符号（>）转（实体符号EntityName:&gt;）或（实体编号EntityNumber十进制:&#62;）
 * @param string $str 要转码的字符串
 * @return string 转码后的字符串
 */
function _html_encode($str) {
    $str = str_replace(">", "&gt;", $str); // 大于号> = &gt; = &#62;
    $str = str_replace("<", "&lt;", $str); // 小于号< = &lt; = &#60;
    $str = str_replace(CHR(9), " ", $str); // ASCII码tab空格CHR(9) = &nbsp; = &#32;
    $str = str_replace(CHR(10), "<br />", $str); // ASCII码换行CHR(10)
    $str = str_replace(CHR(13), " ", $str); // ASCII码回车CHR(13)
    $str = str_replace(CHR(13) & CHR(10), "<br />", $str); // ASCII码回车换行
    $str = str_replace(CHR(32), " ", $str); // ASCII码空格符CHR(32) = &nbsp; = &#32;
    $str = str_replace(CHR(34), "&#34;", $str); // ASCII码双引号" = &quot; = &#34;
    $str = str_replace(CHR(39), "&#39;", $str); // ASCII码单引号' = &apos; = &#39;
    $str = str_replace("\"", "&#34;", $str); // 双引号" = &quot; = &#34;
    $str = str_replace("\'", "&#39;", $str); // 单引号' = &apos; = &#39;
    return $str;
}

/**
 * IPTo_Int() IP地址转换成整数，推荐使用（ 但可以使用替代 ip2long('198.168.3.3') = 3332899587 ）
 * @param string $IP 查询的IP
 * @return int 数字格式
 */
function IPTo_Int($IP) {
    if (!is_ip($IP)) {
        return false;
    } else {
        $ipArr  = explode('.', $IP);
        $ip = $ipArr[0] * 0x1000000
            + $ipArr[1] * 0x10000
            + $ipArr[2] * 0x100
            + $ipArr[3];
        return $ip;
    }
}
// // IP转数字
// echo ip2long('198.168.100.100');
// // 数字转IP
// echo long2ip('3663451078');

/**
 * IntTo_IP() 整数逆转IP地址，推荐使用（ 但可以使用替代 long2ip('3663451078') = 198.168.3.3 ）
 * @param integer $ipVal 转换的数字
 * @return string IP地址
 */
function IntTo_IP($ipVal) {
    $ipArr = array(0 => floor($ipVal / 0x1000000));
    $ipVint   = $ipVal - ($ipArr[0] * 0x1000000); //for clarity
    $ipArr[1] = ($ipVint & 0xFF0000)  >> 16;
    $ipArr[2] = ($ipVint & 0xFF00)  >> 8;
    $ipArr[3] =  $ipVint & 0xFF;
    $ipDotted = implode('.', $ipArr);
    return $ipDotted;
}

/**
 * is_ip 判断IP是否正确
 * @param $ip 要判断的IP地址
 * @return boolean true 或 false
 */
function is_ip($ip) {
    // filter_var(''218.91.21.18'', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)
    // filter_var('2001:0db8:85a3:08d3:1319:8a2e:0370:7334', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)
    if (filter_var($ip, FILTER_VALIDATE_IP)) {
        return true;
    } else {
        return false;
    }
}

/**
 * IntToIP() 整数逆转IP地址，使用另一个，本函数不推荐使用
 * @param $IntValue 转换的数字
 * @return string IP地址
 */
function IntToIP($IntValue) {
    $p4 = $IntValue - intval($IntValue / 256) * 256;
    $IntValue = ($IntValue - $p4) / 256;
    $p3 = $IntValue - intval($IntValue / 256) * 256;
    $IntValue = ($IntValue - $p3) / 256;
    $p2 = $IntValue - intval($IntValue / 256) * 256;
    $IntValue = ($IntValue - $p2) / 256;
    $p1 = $IntValue;
    return (string)$p1 . "." . (string)$p2 . "." . (string)$p3 . "." . (string)$p4;
}

/**
 * IPToInt() IP地址转换成整数，使用另一个，本函数不推荐使用
 * @param string $IP 查询的IP
 * @return int 数字格式
 */
function IPToInt($IP) {
    $IPArray = explode('.', $IP);
    for ($i = 0; $i < 3; $i++) {
        if (!is_numeric($IPArray[$i])) {
            $IPArray[$i] = 0;
        }
        if (intval($IPArray[$i]) < 0) {
            $IPArray[$i] = abs(intval($IPArray[$i]));
        }
        if (intval($IPArray[$i]) > 255) {
            $IPArray[$i] = 255;
        }
    }
    return (intval($IPArray[0]) * 256 * 256 * 256) + (intval($IPArray[1]) * 256 * 256) + (intval($IPArray[2]) * 256) + intval($IPArray[3]);
}

/**
 * CheckIsIp() 判断是否是IP地址，PHP有自己的IP判断方式filter_var()，这个没有用了
 * @param string $_string 查询的IP
 * @return boolean TRUE or FLASE
 */
function CheckIsIp($_string) {
    $patn = "/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)$/";
    if (preg_match($patn, $_string)) {
        return TRUE;
    } else {
        return FALSE;
    }
}

/**
 * getip() 获取访客IP地址
 * @return string IP地址
 * REMOTE_ADDR 访问端IP（有可能是用户，有可能是代理的）
 * HTTP_CLIENT_IP 代理端的（有可能存在，可伪造）是代理服务器发送的HTTP头。如果是“超级匿名代理”，则返回none值。同样，REMOTE_ADDR也会被替换为这个代理服务器的IP。
 * HTTP_X_FORWARDED_FOR 用户是在哪个IP使用的代理（有可能存在，也可以伪造）
 */
function getip() {
    static $ip = '';
    $ip = $_SERVER['REMOTE_ADDR'];
    if (isset($_SERVER['HTTP_CDN_SRC_IP'])) {
        $ip = $_SERVER['HTTP_CDN_SRC_IP'];
    } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) and preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
        foreach ($matches[0] as $xip) {
            if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
                $ip = $xip;
                break;
            }
        }
    }
    return $ip;
}

function compare_time($start_date, $end_date) {

    // $date1 = strtotime("2016-06-01 22:45:00");
    // $date2 = strtotime("2018-09-21 10:44:01");
    $start_date = strtotime($start_date);
    $end_date = strtotime($end_date); 
    //计算两个日期之间的时间差
    $diff = $end_date - $start_date;
    //转换时间差的格式
    if ($diff <= 0) {
        return 0;
    } elseif ($diff < 60) {
        return $diff. ' 秒';
    } elseif ($diff < (60 * 60)) {
        $min = intval($diff % (60 * 60 * 24) % 3600 / 60);
        $sec = intval($diff % (60 * 60 * 24) % 3600 % 60);
        return $min . ' 分 ' . $sec . ' 秒';
    } elseif ($diff < (60 * 60 * 24)) {
        $hou = intval($diff / (60 * 60));
        $min = intval($diff % (60 * 60 * 24) % 3600 / 60);
        $sec = intval($diff % (60 * 60 * 24) % 3600 % 60);
        return $hou . ' 时 ' . $min . ' 分 ' . $sec . ' 秒';
    } elseif ($diff < (365 * 60 * 60 * 24)) {
        $years = floor($diff / (365 * 60 * 60 * 24));
        $months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));
        $days = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24) / (60 * 60 * 24));
        $hours = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24) / (60 * 60));
        $minutes = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24 - $hours * 60 * 60) / 60);
        $seconds = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24 - $hours * 60 * 60 - $minutes * 60));
        // printf("相差：%d 年, %d 月, %d 日, %d 小时, %d 分, %d 秒", $years, $months, $days, $hours, $minutes, $seconds);
        return $months . ' 月 ' . $days . ' 天 ' . $hours . ' 时 ' . $minutes . ' 分 ' . $seconds . ' 秒';
    } else {
        $years = floor($diff / (365 * 60 * 60 * 24));
        $months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));
        $days = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24) / (60 * 60 * 24));
        $hours = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24) / (60 * 60));
        $minutes = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24 - $hours * 60 * 60) / 60);
        $seconds = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24 - $days * 60 * 60 * 24 - $hours * 60 * 60 - $minutes * 60));
        // printf("相差：%d 年, %d 月, %d 日, %d 小时, %d 分, %d 秒", $years, $months, $days, $hours, $minutes, $seconds);
        return $years . ' 年 ' . $months . ' 月 ' . $days . ' 天 ' . $hours . ' 时 ' . $minutes . ' 分 ' . $seconds . ' 秒';
    }
// var $min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
// var sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
// $years = floor($diff / (365*60*60*24)); 
// $months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
// $days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24) / (60*60*24));
// $hours = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24) / (60*60));
// $minutes = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60)/ 60);
// $seconds = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60 - $minutes*60));
// printf("相差：%d 年, %d 月, %d 日, %d 小时, %d 分, %d 秒", $years, $months, $days, $hours, $minutes, $seconds);
}


/**
 * isDiffTimes() 对比2个时间是否一致
 * @param integer|string $last_date 时间一
 * @param integer|string $this_date 时间二
 * @param int $diff_type, 1比较年是否相同，2比较月是否相同，3比较日是否相同，4比较小时否相同，5比较分钟否相同，6比较周几是否相同，其它为比较日
 */ 
//判断两天是否是同一天
function isDiffTimes($last_date, $this_date, $diff_type = 3) {
    if (!$last_date) {
        return false;
    }
    if (!$this_date) {
        return false;
    }
    if (strlen($last_date) < 8 ) {
        return false;
    }
    if (strlen($this_date) < 8) {
        return false;
    }
    // 如果不是时间戳，就先转为时间戳
    if (!is_stamp($last_date)) {
        $last_date = strtotime($last_date);
    }
    if (!is_stamp($this_date)) {
        $this_date = strtotime($this_date);
    }
    // 如果还不是时间戳，返回false
    if (!$last_date) {
        return false;
        
    }
    if (!$this_date) {
        return false;
    }
    if ($diff_type == 1) {
        // 使用getdate比较 年year 是否都相同
        if ((getdate($last_date)['year'] === getdate($this_date)['year'])) {
            return true;
        } else {
            return false;
        }
    } elseif ($diff_type == 2) {
        // 使用getdate比较 年year 和 月mon（月份的数字） 是否都相同
        if ((getdate($last_date)['year'] === getdate($this_date)['year']) && (getdate($last_date)['mon'] === getdate($this_date)['mon'])) {
            return true;
        } else {
            return false;
        }
    } elseif ($diff_type == 3) {
        // 使用getdate比较 年year 和 一年中的天数yday 是否都相同
        if ((getdate($last_date)['year'] === getdate($this_date)['year']) && (getdate($last_date)['yday'] === getdate($this_date)['yday'])) {
            return true;
        } else {
            return false;
        }
    } elseif ($diff_type == 4) {
        // 使用getdate比较 年year 和 一年中的天数yday 小时hours 是否都相同
        if ((getdate($last_date)['year'] === getdate($this_date)['year']) && (getdate($last_date)['yday'] === getdate($this_date)['yday']) && (getdate($last_date)['hours'] === getdate($this_date)['hours'])) {
            return true;
        } else {
            return false;
        }
    } elseif ($diff_type == 5) {
        // 使用getdate比较 年year 和 一年中的天数yday 小时hours 分钟minutes 是否都相同
        if ((getdate($last_date)['year'] === getdate($this_date)['year']) && (getdate($last_date)['yday'] === getdate($this_date)['yday']) && (getdate($last_date)['hours'] === getdate($this_date)['hours']) && (getdate($last_date)['minutes'] === getdate($this_date)['minutes'])) {
            return true;
        } else {
            return false;
        }
    } elseif ($diff_type == 6) {
        // 使用getdate比较 年year 和 月mon（月份的数字） 星期wday 是否都相同
        if ((getdate($last_date)['year'] === getdate($this_date)['year'])&& (getdate($last_date)['mon'] === getdate($this_date)['mon']) && (getdate($last_date)['wday'] === getdate($this_date)['wday'])) {
            return true;
        } else {
            return false;
        }
    } else {
        // 使用getdate比较 年year 和 一年中的天数yday 是否都相同
        if ((getdate($last_date)['year'] === getdate($this_date)['year']) && (getdate($last_date)['yday'] === getdate($this_date)['yday'])) {
            return true;
        } else {
            return false;
        }
    } 
}

//返回当前的毫秒时间戳
function msectime() {
    list($msec, $sec) = explode(' ', microtime());
    $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    return $msectime;
}

/**
 * is_stamp 检查是否是正确的时间戳
 * @param int|string $timestamp 是一个时间戳字符串 或 时间戳数字
 * @return boolean true or false
 */
function is_stamp($timestamp) {
    if (gettype($timestamp) != 'integer') {
        // 如果不是整数类型，就要判断是否可以转为整数
        // 先转换为整数（111.02=111，11aa=11，a11=0）后，再转为字符 并和原数据对比看是否相同（11aa= 11对比11aa）
        // 111.0= 111对比111.0时，使用 !== 返回false
        if (strval(intval($timestamp)) !== strval($timestamp)) {
            return false;
        }
        // 如果字符和数字相互转换后还能相同，把转为整数参与下面功能对比使用。
        $timestamp = intval($timestamp);
    }
    // 先把时间戳转为时间，再转为时间戳 后和原数据对比
    if (strtotime(date('Y-m-d H:i:s', $timestamp)) === $timestamp) {
        return true;
    } else {
        return false;
    }
}

/**
 * _date 返回指定格式日期
 * @param int $_type
 * @param null | timestamp : $_date 日期时间戳 或 参数为空
 * @return string 格式化的日期
 */
function d_time($_type = 1, $_date = null) {
    if (empty($_date)) {
        $_date = null;
    } else {
        if (gettype($_date) != 'integer') {
            // 如果不是整数类型，就要判断是否可以转为整数
            if (strval(intval($_date)) !== strval($_date)) {
                exit('时间戳不正确');
            }
            $_date = intval($_date);
        }
    }
    if ($_type == 11 || $_type == 12) {
        // 实例化带微秒的类对象
        $date_time = new DateTime();
    }
    switch ($_type) {
        case 1:
            return date('Ymd', $_date);
        case 2:
            return date('ymd', $_date);
        case 3:
            return date('Y-m-d', $_date);
        case 4:
            return date('y-m-d', $_date);
        case 5:
            return date('Y年m月d日', $_date);
        case 6:
            return date('Y/m/d', $_date);
        case 7:
            return date('Ym', $_date);
        case 8:
            return date('md', $_date);
        case 9:
            return date('YmdHis', $_date);
        case 10:
            return date('mdHis', $_date);
        case 11:
            return $date_time->format('YmdHisv'); // 3位的毫秒v，显示为系统时间
        case 12:
            return $date_time->format('YmdHisu'); // 6位的微秒u，显示为系统时间
        case 13:
            return date('Y-m-d H:i:s', $_date);
        default:
            return date('Ymd'); // 显示为系统时间
    }
}

/**
 * _is_catalog验证是否 数字、字母、下划线，并且5-16位
 * @param string $str 目录名
 * @param string $_tipstext 错误时提示文字
 * @return string |prompt 正确返回$str， 错误时弹窗提示
 */
function _is_catalog($str, $_tipstext) {
    if (preg_match('/^[_0-9a-z]{5,16}$/i', $str)) {
        return $str;
    } else {
        _alert_back($_tipstext);
    }
}

/**
 * _get_site_url 获取当前站点的路径（查找 $repl_catalog 在 $url_all 中的第一次出现，并返回字符串的剩余部分（前面））
 * @param string $repl_catalog 查找并替换的目录名
 * @return string 网址 $repl_catalog 前面部分
 */
function _get_site_url($repl_catalog) {
    $url_all = _is_https() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    // stristr 不区分大小写，或用strstr区分大小写，stristr(a,b,true)，true返回前面字符，false返回后面字符
    $site_url = stristr($url_all, $repl_catalog, true); //查找 $repl_catalog 在 $url_all 中的第一次出现，并返回字符串的剩余部分（前面）
    return $site_url;
}

/**
 * get_url 获取指定URL或当前URL信息
 * @param string $get_type 要显示URL的类型，1网址文件名前的部分，2带http的完整的域名，3不带http的的域名，4url的文件名，5url的文件扩展名，6url中所有参数，其它或空:完整网址
 * @param string $url 指定的网址，如果为空则为当前访问URL
 * @return string|null 按指定类型返回网址部分
 */
function get_url($get_type = 0, $url = null) {
    // 如果指定了url就使用指定的
    if ($url) {
        if (check_url($url)) {
            $url_all = $url;
        } else {
            // FILTER_VALIDATE_URL 过滤器把值作为 URL 来验证， FILTER_FLAG_HOST_REQUIRED(7.3已经废弃) 要求 URL 包含主机名。
            if (filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)) {
                $url_all = $url;
            } else {
                return null;
            }
        }
    } else {
        $url_all = _is_https() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }
    $url_arr = parse_url($url_all);
    switch ($get_type) {
        case 1:
            return substr($url_all, 0, strripos($url_all, '/')); // 网址文件名前的部分（当前文件名所在最终目录）
            break;
        case 2:
            return $url_arr['scheme'].'://'.$url_arr['host']; // 带http的完整的域名
            break;
        case 3:
            return $url_arr['host']; // 不带http的的域名
            break;
        case 4:
            return basename($url_arr['path']); // url的文件名
            break;
        case 5:
            return explode('.', basename($url_arr['path']))[1]; // url的文件扩展名
            break;
        case 6:
            return isset($url_arr['query'])? $url_arr['query']:''; // url中所有参数
            break;
        default:
            return $url_all; // 完整网址
            break;
    }
}

/**
 * check_url检测域名格式是否正确
 * @param string $c_url 要检查的URL
 * @return boolean 成功true，失败false
 */
function check_url($c_url) {
    $str = "/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/i";
    if (!preg_match($str, $c_url)) {
        return false;
    } else {
        return true;
    }
}

/**
 * _post_isset() 判断$_POST['id']指定参数是否存在，并赋值
 * @param string $_string 查询的参数名
 * @return string|void 过滤后的字符串|空
 */
function _post_get_isset($key)
{
    $_string = _post_isset($key);
    if (!$_string && $_string != "0") {
        $_string = _get_isset($key);
    }
    return $_string;
}

/**
 * _get_isset() 判断$_GET['id']指定参数是否存在，并赋值
 * @param string $_string 查询的参数名
 * @return string|void 过滤后的字符串|空
 */
function _get_isset($_string) {
    // 如果参数名存在，先转为小写
    if ($_string) {
        $_string = strtolower($_string);
    } else {
        return '';
    }
    if (isset($_GET[$_string])) {
        return trim($_GET[$_string]);
    } else {
        return '';
    }
}

/**
 * _post_isset() 判断$_POST['id']指定参数是否存在，并赋值
 * @param string $_string 查询的参数名
 * @return string|void 过滤后的字符串|空
 */
function _post_isset($_string) {
    // 如果参数名存在，先转为小写
    if ($_string) {
        $_string = strtolower($_string);
    } else {
        return '';
    }
    if (isset($_POST[$_string])) {
        return trim($_POST[$_string]);
    } else {
        return '';
    }
}

/**
 * _is_num() 判断是否数字，如果否:返回0，是:格式化为整数
 * @param int $_num 要检查的数字
 * @return int 0|int 返回 0 或 整数数字
 */
function _is_num($_num) {
    if (!isset($_num) || $_num == "") {
        $_num = 0;
    }
    if (is_numeric($_num)) {
        $_num = intval($_num);
    } else {
        $_num = 0;
    }
    return $_num;
}

/**
 * _text_len 返回指定长度的字符串（中英文长度都为1）
 * @param string $_string 要处理的字符串
 * @param int $_length 保留的字符串的长度
 * @return string 按长度截取后新的字符串
 */
function _text_len($_string, $_length) {
    // mb_strlen中文长度为1
    if (mb_strlen($_string, 'utf-8') > $_length) {
        $_string = mb_substr($_string, 0, $_length, 'utf-8') . '...'; // mb_substr中文长度为1
    }
    return $_string;
}

/**
 * _html() 使用htmlspecialchars()过滤html中安全字符
 * 如果是数组，拆开后使用数组循环方式过滤，否则直接过滤。
 * @param string $_string 未过滤前的字符或数组
 * @return string 过滤后的字符或数据
 */
function _html($_string) {
    // 如果是数组就循环数组并调用_html函数本身
    if (is_array($_string)) {
        foreach ($_string as $_key => $_value) {
            $_string[$_key] = _html($_value); //采用递归方式，执行函数自己
        }
    } else {
        $_string = htmlspecialchars($_string);
        // $_string=str_replace('\r\n',CHR(13),$_string);
        // $_string=str_replace('\r',CHR(13),$_string);
        // $_string=str_replace('\n',CHR(10),$_string);
    }
    return $_string;
}

function sweetOneAlert($aTitle, $bCont) {
    echo "<script language='JavaScript' type='text/JavaScript'>oneAlert('" . $aTitle . "','" . $bCont . "');</script>";
    exit;
}
function sweetTwoAlert($aTitle, $bCont, $confGoUrl) {
    echo "<script language='JavaScript' type='text/JavaScript'>twoAlert('" . $aTitle . "','" . $bCont . "','" . $confGoUrl . "');</script>";
    exit;
}
function sweettwoAlertBack($aTitle, $bCont) {
    echo "<script language='JavaScript' type='text/JavaScript'>twoAlertBack('" . $aTitle . "','" . $bCont . "');</script>";
    exit;
}

function sweetThreeAlert($aTitle, $bCont, $confGoUrl, $canGoUrl) {
    echo "<script language='JavaScript' type='text/JavaScript'>threeAlert('" . $aTitle . "','" . $bCont . "','" . $confGoUrl . "','" . $canGoUrl . "');</script>";
    exit;
}


/**
 * _alert_goto() 表示JS弹窗，可返回指定网址
 * @param string $_tipsText 提示文字
 * @param string $_gotoUrl 返回指定网址
 * @return void (prompt|location) JS弹窗|跳转网址
 */
function _alert_goto($_tipstext = '非法操作', $_gotourl) {
    // 如果有提示文字，弹窗后跳转到$_gotourl，或返回上一页。 否则不提示直接导向到$_gotourl
    if (!empty($_tipstext)) {
        if (!empty($_gotourl)) {
            echo "<script type='text/javascript'>alert('" . $_tipstext . "');location.href='" . $_gotourl . "';</script>";
            exit();
        } else {
            echo "<script type='text/javascript'>alert('" . $_tipstext . "');history.back();</script>";
            exit();
            // echo "<script type='text/javascript'>alert('非法操作！');history.go(-1);</script>";
        }
    } else {
        header('location:' . $_gotourl);
    }
}

/**
 * _alert_back() 表示JS弹窗，可返回上一页
 * @param string $_tipsText 提示文字
 * @return void (prompt) JS弹窗
 */
function _alert_back($_tipstext = '非法操作！') {
    // 弹窗提示并返回上一页
    echo "<script type='text/javascript'>alert('" . $_tipstext . "');history.back();</script>";
    exit();
}

/**
 * _alert_close() 提示后关闭本窗口
 * @param string $_tipstext 提示文字
 * @return void (prompt) JS弹窗后关闭
 */
function _alert_close($_tipstext = '非法操作！') {
    // 弹窗提示后关闭本窗口，有的浏览器不能被关闭
    echo "<script type='text/javascript'>alert('" . $_tipstext . "');window.close();</script>";
    exit();
}

/**
 * _check_code() 后台登录验证码对比
 * @param string $_first_code 输入的验证码
 * @param string $_session_code Session中生成的验证码
 * @param string $_backurl 弹窗返回网址
 * @return void (|prompt) 验证码比对不通过弹窗，通过时无动作
 */
function _check_code($_first_code, $_session_code, $_backurl) {
    // 将1和2参数对比，如果不同提示错误
    if (empty($_first_code) || empty($_session_code)) {
        _alert_goto('验证码不能为空', $_backurl);
    }
    if (strtolower($_first_code) != strtolower($_session_code)) {
        _alert_goto('验证码错误或已失效', $_backurl);
    }
}

/**
 * _check_str_len 验证字符串是否符合要求长度 
 * @param string $_string 要验证字符串
 * @param int $_min_num 最小长度
 * @param int $_max_num 最大长度
 * @param string $_tipsText 未验证通过时提示文字
 * @param string $_gotourl 未难通过时跳转网址
 * @return string (|prompt) 验证通过，返回原字符串
 */
function _check_str_len($_string, $_min_num, $_max_num, $_tipsText, $_gotourl) {
    $_string = trim($_string); //去掉两边的空格
    //长度少于$_min_num位或大于$_max_num位都不行
    if (mb_strlen($_string, 'utf-8') < $_min_num || mb_strlen($_string, 'utf-8') > $_max_num) {
        _alert_goto($_tipsText . ' 不能少于 ' . $_min_num . ' 位或大于 ' . $_max_num . ' 位', $_gotourl);
    }
    return $_string;
}

/**
 * _chk_username() 验证用户名是否合法
 * @param string $_string 提交未验证的用户名
 * @param int $_min_num 用户名最小位数
 * @param int $_max_num 用户名最大位数
 * @return string $_string 验证用户名字符串
 */
function _chk_username($_string, $_min_num, $_max_num) {
    //去掉两边的空格
    $_string = trim($_string);
    //长度少于2位或大于20位都不行
    if (mb_strlen($_string, 'utf-8') < $_min_num || mb_strlen($_string, 'utf-8') > $_max_num) {
        _alert_goto('用户名长度不能少于' . $_min_num . '位或大于' . $_max_num . '位', '../dream_merchant/login.php');
    }
    //限制敏感字符（单引号、双引号、空格、全角空格）
    $_char_pattern = '/[<>*.\'\"\ ]/';
    if (preg_match($_char_pattern, $_string)) {
        _alert_goto('用户名不得包含敏感字符', '../dream_merchant/login.php');
    }
    return $_string;
}

/**
 * _chk_pwd_url() 验证用户输入的密码
 * @param string $_first_pass 密码
 * @param string $_end_pass 确认密码
 * @param int $_min_num 密码最小位数
 * @param int $_max_num 密码最大位数
 * @return string $_first_pass 返回可用的密码
 */
function _chk_pwd_url($_first_pass, $_min_num, $_max_num, $backurl) {
    //判断密码为空
    if ($_first_pass == "") {
        _alert_goto('密码不能为空', $backurl);
    }
    //判断密码长度
    if (strlen($_first_pass) < $_min_num || strlen($_first_pass) > $_max_num) {
        _alert_goto('密码不得小于' . $_min_num . '位或大于' . $_max_num . '位', $backurl);
    }
    //密码sha1加密返回结果
    return _sha256($_first_pass);
}

/**
 * _chk_password() 验证用户输入的密码
 * @param string $_first_pass 密码
 * @param string $_end_pass 确认密码
 * @param int $_min_num 密码最小位数
 * @param int $_max_num 密码最大位数
 * @return string $_first_pass 返回可用的密码
 */
function _chk_password($_first_pass, $_min_num, $_max_num) {
    //判断密码为空
    if ($_first_pass == "") {
        _alert_goto('密码不能为空', '../dream_merchant/login.php');
    }
    //判断密码长度
    if (strlen($_first_pass) < $_min_num || strlen($_first_pass) > $_max_num) {
        _alert_goto('密码不得小于' . $_min_num . '位或大于' . $_max_num . '位', '../dream_merchant/login.php');
    }
    //密码sha1加密返回结果
    return _sha256($_first_pass);
}

/**
 * br2nl 将html中的<br />换行符替换为空，并替换为文本框中的换行符
 * @param string $text 要过滤的原文字
 * @return string 过滤后的新文字
 */
function br2nl($text) {
    return preg_replace('/<br\\s*?\/??>/i', '', $text);
}

/**
 * _is_https() PHP判断当前协议是否为HTTPS
 * @return string https:// or http://
 */
function _is_https() {
    if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
        return "https://"; //return true
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        return "https://"; //return true
    } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
        return "https://"; //return true
    } elseif (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] == 'https') {
        return "https://"; //return true
    } elseif (isset($_SERVER['HTTP_X_CLIENT_SCHEME']) && $_SERVER['HTTP_X_CLIENT_SCHEME'] == 'https') {
        return "https://"; //return true
    } elseif ($_SERVER['SERVER_PORT'] == 443) {
        return "https://"; //return true
    } else {
        return "http://"; //return false
    }
}

/**
 * isMobile() 判断访客是手机 或 PC
 * @return boolean true or false
 */
function isMobile() {
    // 从HTTP_USER_AGENT中提取对比数据
    $useragent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    $useragent_commentsblock = preg_match('|\(.*?\)|', $useragent, $matches) > 0 ? $matches[0] : '';
    function CheckSubstrs($substrs, $text)
    {
        foreach ($substrs as $substr)
            if (false !== strpos($text, $substr)) {
                return true;
            }
        return false;
    }
    $mobile_os_list = array('Google Wireless Transcoder', 'Windows CE', 'WindowsCE', 'Symbian', 'Android', 'armv6l', 'armv5', 'Mobile', 'CentOS', 'mowser', 'AvantGo', 'Opera Mobi', 'J2ME/MIDP', 'Smartphone', 'Go.Web', 'Palm', 'iPAQ');
    $mobile_token_list = array('Profile/MIDP', 'Configuration/CLDC-', '160×160', '176×220', '240×240', '240×320', '320×240', 'UP.Browser', 'UP.Link', 'SymbianOS', 'PalmOS', 'PocketPC', 'SonyEricsson', 'Nokia', 'BlackBerry', 'Vodafone', 'BenQ', 'Novarra-Vision', 'Iris', 'NetFront', 'HTC_', 'Xda_', 'SAMSUNG-SGH', 'Wapaka', 'DoCoMo', 'iPhone', 'iPod');
    $found_mobile = CheckSubstrs($mobile_os_list, $useragent_commentsblock) ||
        CheckSubstrs($mobile_token_list, $useragent);
    if ($found_mobile) {
        return 1;
    } else {
        return 0;
    }
}

/**
 * getOS(0) 获取操作系统类型
 * @param int $isFilter 空 或 0 直接显示系统及版本。 1 清除《 空格/._ (),; 》字符
 * @return string 匹配后的操作系统类型
 */
function getOS($isFilter = 0) {
    $os = '';
    // 从HTTP_USER_AGENT中提取对比数据
    $agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    if (preg_match('/win/i', $agent) && preg_match('/nt 10.0/i', $agent)) {
        $os = 'Windows 10';
    } elseif (preg_match('/win/i', $agent) && preg_match('/nt 6.3/i', $agent)) {
        $os = 'Windows Server 2012';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.2/i', $agent)) {
        $os = 'Windows 8';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.1/i', $agent)) {
        $os = 'Windows 7';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.0/i', $agent)) {
        $os = 'Windows Vista';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5.2/i', $agent)) {
        $os = 'Windows Server 2003';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5.1/i', $agent)) {
        $os = 'Windows XP';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5.0/i', $agent)) {
        $os = 'Windows 2000';
    } else if (preg_match('/win 9x/i', $agent) && strpos($agent, '/4.90/i')) {
        $os = 'Windows ME';
    } else if (preg_match('/win/i', $agent) && preg_match('/98/i', $agent)) {
        $os = 'Windows 98';
    } else if (preg_match('/win/i', $agent) && strpos($agent, '/95/i')) {
        $os = 'Windows 95';
    } else if (preg_match('/win/i', $agent) && preg_match('/32/i', $agent)) {
        $os = 'Windows 32';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt/i', $agent)) {
        $os = 'Windows NT';
    } else if (preg_match('/harmony/i', $agent)) {
        $os = 'HarmonyOS';
    } else if (preg_match('/linux/i', $agent) && preg_match('/android([\d]*) ([^\s|;]+)/i', $agent, $regs)) {
        $os = 'Android' . $regs[2];
    // } elseif (preg_match('/android([\d]*) ([^\s|;]+)/i', $agent, $regs)) {
    //     $os = 'Android' . $regs[2];
    } elseif (preg_match('/android/i', $agent)) {
        $os = 'Android';
    } elseif (preg_match('/iphone os([\d]*) ([^\s]+)/i', $agent, $regs)) {
        $os = 'iPhone' . $regs[2];
    } elseif (preg_match('/iphone/i', $agent)) {
        $os = 'iPhone';
    } elseif (preg_match('/ipad.*?os[\s]*([\w]*([^\s]|;))+/i', $agent, $regs)) {
        $os = 'iPad' . $regs[1];
    } elseif (preg_match('/ipad/i', $agent, $regs)) {
        $os = 'iPad';
    } elseif (preg_match('/linux/i', $agent)) {
        $os = 'Linux';
    } elseif (preg_match('/unix/i', $agent)) {
        $os = 'Unix';
    } elseif (preg_match('/sun/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'SunOS';
    } elseif (preg_match('/ibm/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'IBM OS/2';
    } elseif (preg_match('/mac/i', $agent) && preg_match('/pc/i', $agent)) {
        $os = 'Macintosh';
    } elseif (preg_match('/PowerPC/i', $agent)) {
        $os = 'PowerPC';
    } elseif (preg_match('/AIX/i', $agent)) {
        $os = 'AIX';
    } elseif (preg_match('/HPUX/i', $agent)) {
        $os = 'HPUX';
    } elseif (preg_match('/NetBSD/i', $agent)) {
        $os = 'NetBSD';
    } elseif (preg_match('/BSD/i', $agent)) {
        $os = 'BSD';
    } elseif (preg_match('/OSF1/i', $agent)) {
        $os = 'OSF1';
    } elseif (preg_match('/IRIX/i', $agent)) {
        $os = 'IRIX';
    } elseif (preg_match('/FreeBSD/i', $agent)) {
        $os = 'FreeBSD';
    } elseif (preg_match('/Palmsource/i', $agent) || preg_match('/PalmOS/i', $agent)) {
        $os = 'PalmOS';
    } else if (preg_match('/teleport/i', $agent)) {
        $os = 'teleport';
    } else if (preg_match('/flashget/i', $agent)) {
        $os = 'flashget';
    } else if (preg_match('/webzip/i', $agent)) {
        $os = 'webzip';
    } else if (preg_match('/offline/i', $agent)) {
        $os = 'offline';
    } elseif ($os == '') {
        $os = 'Unknown';
    } else {
        $os = 'Unknown1';
    }
    if ($isFilter) {
        $fil_arr = array('/', ' ', '.', '_', '(', ')', ';', ',');
        $os = str_replace($fil_arr, '', $os);
        return $os;
    } else {
        return $os;
    }
}

/**
 * 获取客户端浏览器以及版本号
 * @param $agent    //$_SERVER['HTTP_USER_AGENT']
 * @return array [browser|browser_ver] 浏览器名称|浏览器版本号
 * @return array Example: $borinfo['browser'] . $borinfo['browser_ver']
 */
function getClientBrowser() {
    // 从HTTP_USER_AGENT中提取对比数据
    $agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    $browser = '';
    $browser_ver = '';
    if (preg_match('/OmniWeb\/(v*)([^\s|;]+)/i', $agent, $regs)) {
        $browser = 'OmniWeb';
        $browser_ver = $regs[2];
    }
    if (preg_match('/Netscape([\d]*)\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'Netscape';
        $browser_ver = $regs[2];
    }
    if (preg_match('/safari\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'Safari';
        $browser_ver = $regs[1];
    }
    if (preg_match('/MSIE\s([^\s|;]+)/i', $agent, $regs)) {
        $browser = 'Internet Explorer';
        $browser_ver = $regs[1];
    }
    if (preg_match('/Opera[\s|\/]([^\s]+)/i', $agent, $regs)) {
        $browser = 'Opera';
        $browser_ver = $regs[1];
    }
    if (preg_match('/NetCaptor\s([^\s|;]+)/i', $agent, $regs)) {
        $browser = '(Internet Explorer ' . $browser_ver . ') NetCaptor';
        $browser_ver = $regs[1];
    }
    if (preg_match('/Maxthon/i', $agent, $regs)) {
        $browser = '(Internet Explorer ' . $browser_ver . ') Maxthon';
        $browser_ver = '';
    }
    if (preg_match('/360SE/i', $agent, $regs)) {
        $browser = '(Internet Explorer ' . $browser_ver . ') 360SE';
        $browser_ver = '';
    }
    if (preg_match('/SE 2.x/i', $agent, $regs)) {
        $browser = '(Internet Explorer ' . $browser_ver . ') 搜狗';
        $browser_ver = '';
    }
    if (preg_match('/FireFox\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'FireFox';
        $browser_ver = $regs[1];
    }
    if (preg_match('/Lynx\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'Lynx';
        $browser_ver = $regs[1];
    }
    if (preg_match('/Chrome\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'Chrome';
        $browser_ver = $regs[1];
    }
    if (preg_match('/MicroMessenger\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'MicroMessenger';
        $browser_ver = $regs[1];
    }
    if (preg_match('/TheWorld([\d]*) ([^\s]+)/i', $agent, $regs)) {
        $browser = 'TheWorld';
        $browser_ver = $regs[2];
    }
    if (preg_match('/MQQBrowser([\d]*)\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'MQQBrowser';
        $browser_ver = $regs[2];
    }
    if (preg_match('/HuaweiBrowser([\d]*)\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'HuaweiBrowser';
        $browser_ver = $regs[2];
    }
    if (preg_match('/UBrowser([\d]*)\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'UC';
        $browser_ver = $regs[2];
    }
    if (preg_match('/Edg([\d]*)\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'Edge';
        $browser_ver = $regs[2];
    }
    if (preg_match('/Maxthon([\d]*)\/([^\s]+)/i', $agent, $regs)) {
        $browser = 'Maxthon';
        $browser_ver = $regs[2];
    }
    //return $browser.$browser_ver;
    if ($browser != '') {
        return ['browser' => $browser, 'browser_ver' => $browser_ver];
    } else {
        return ['browser' => 'unknown', 'browser_ver' => ''];
    }
}

/**
 * PHP的 sha256 sha512（PHP 7.1）没有内置的函数来计算。
 * sha1() sha1_file() md5() md5_file() 分别可以用来计算字符串和文件的sha1散列值和md5散列值。
 * 版本PHP7.1中 sha256() sha256_file() sha512() sha512_file()这样的函数也没有。
 * SHA-2 是 SHA-224、SHA-256、SHA-384，和 SHA-512的合称。
 * PHP计算sha256 sha512可以使用hash()函数实现，计算文件的sha256 sha512则可以使用hash_file()实现。
 * hash($algo , $data, $rawOutput); 计算文字hash
 * hash_file($algo , $filepath, $rawOutput); 计算文件hash
 * 我们可以封装自定义函数来实现PHP计算 sha256 sha512 以及其他类型的hash值。
 * 以下代码实现PHP sha256() sha256_file() sha512() sha512_file() PHP 5.1.2+完美兼容
 * @param string $algo 是算法，可以是 sha256, sha512 等值，支持的算法可以使用hash_algos()查看，该函数返回所有支持的算法。
 * @param string $data 是需要计算hash值的字符串
 * @param string $filepath 是需要计算散列值hash值的文件名，可以是相对路径或绝对路径；单独的文件名或包含路径的文件名
 * @param boolean $rawOutput 是一个可选的布尔值参数，为 true 返回二进制数据，为 false 则返回字符串，默认值为false。
 * @return boolean|string 参数无效、或者文件不存在、或者文件不可读时，返回false，计算成功则返回对应的散列值。
 * @return false|string 文字Example: _sha256('www.quhuichang.cn') _sha512('www.quhuichang.cn')
 * @return false|string 文件Example: _sha256_file('index.php') _sha512_file('../m/index.php')
 **/

/**
 * _sha256 对字符进行hash(sha256)加密，长度为64
 * @param string $data 要加密的文字
 * @param boolean $rawOutput 返回加密方式：true返回二进制数据，false返回字符串
 * @return false|string 失败时返回false，成功返回string(长度64) 或 Binary
 */
function _sha256($data, $rawOutput = false) {
    // is_scalar()函数用于检测变量是否是一个标量（标量变量是指包含了integer、float、string或boolean的变量，而array、object和resource则不是标量）
    if (!is_scalar($data)) {
        return false;
    }
    $data = (string)$data;
    // !!双重否定值， !为否定(!3.1415=false,!aaa=false)，!!为否定后再否定(!!3.1415=true,!!aaa=true)，参数不管是什么值最终都保证是false或true
    $rawOutput = !!$rawOutput;
    return hash('sha256', $data, $rawOutput);
}

/**
 * _sha256_file 对文件进行hash(sha256)加密，长度为64
 * @param string $file 要加密的文件路径
 * @param boolean $rawOutput 返回加密方式：true返回二进制数据，false返回字符串
 * @return false|string 失败时返回false，成功返回string 或 Binary
 */
function _sha256_file($file, $rawOutput = false) {
    // is_scalar()函数用于检测变量是否是一个标量（标量变量是指包含了integer、float、string或boolean的变量，而array、object和resource则不是标量）
    if (!is_scalar($file)) {
        return false;
    }
    $file = (string)$file;
    // is_file判断给定文件名是否为一个正常的文件。 is_readable()函数检查指定的文件是否可读。
    if (!is_file($file) || !is_readable($file)) {
        return false;
    }
    // !!双重否定值， !为否定(!3.1415=false,!aaa=false)，!!为否定后再否定(!!3.1415=true,!!aaa=true)，参数不管是什么值最终都保证是false或true
    $rawOutput = !!$rawOutput;
    return hash_file('sha256', $file, $rawOutput);
}

/**
 * _sha512 对字符进行hash(sha512)加密，长度为128
 * @param string $data 要加密的文字
 * @param boolean $rawOutput 返回加密方式：true返回二进制数据，false返回字符串
 * @return false|string 失败时返回false，成功返回string 或 Binary
 */
function _sha512($data, $rawOutput = false) {
    // is_scalar()函数用于检测变量是否是一个标量（标量变量是指包含了integer、float、string或boolean的变量，而array、object和resource则不是标量）
    if (!is_scalar($data)) {
        return false;
    }
    $data = (string)$data;
    // !!双重否定值， !为否定(!3.1415=false,!aaa=false)，!!为否定后再否定(!!3.1415=true,!!aaa=true)，参数不管是什么值最终都保证是false或true
    $rawOutput = !!$rawOutput;
    return hash('sha512', $data, $rawOutput);
}

/**
 * _sha512_file 对文件进行hash(sha512)加密，长度为128
 * @param string $file 要加密的文件路径
 * @param boolean $rawOutput 返回加密方式：true返回二进制数据，false返回字符串
 * @return false|string 失败时返回false，成功返回string 或 Binary
 */
function _sha512_file($file, $rawOutput = false) {
    // is_scalar()函数用于检测变量是否是一个标量（标量变量是指包含了integer、float、string或boolean的变量，而array、object和resource则不是标量）
    if (!is_scalar($file)) {
        return false;
    }
    $file = (string)$file;
    // is_file判断给定文件名是否为一个正常的文件。 is_readable()函数检查指定的文件是否可读。
    if (!is_file($file) || !is_readable($file)) {
        return false;
    }
    // !!双重否定值， !为否定(!3.1415=false,!aaa=false)，!!为否定后再否定(!!3.1415=true,!!aaa=true)，参数不管是什么值最终都保证是false或true
    $rawOutput = !!$rawOutput;
    return hash_file('sha512', $file, $rawOutput);
}

/**
 * enc_b64ts 将传来的字符串添加当前时间戳后，进行Base64加密
 * @param string $str 传来的字符串
 * @return string 返回base64编码后的字符串
 */
function enc_b64ts($str) {
    // 原始数据连接时间戳
    $newstr = $str . '.' . time();
    $info_b64str = b64_Encode($newstr);
    return $info_b64str;
}

/**
 * dec_b64ts 将字符串进行base64解密后，去除时间戳后获取使用字符串
 * @param string $str 需要使用base64解码的字符串
 * @return string 解密后，去除时间戳后的字符串
 */
function dec_b64ts($str) {
    $info_b64str = b64_Decode($str);
    $tokens = explode('.', $info_b64str);
    if (count($tokens) != 2) {
        return false;
    }
    list($newstr, $time_stamp) = $tokens;
    if (isset($newstr)) {
        return $newstr;
    } else {
        return false;
    }
}

/**
 * b64_Encode()将数据进行base64编码
 * @param string $input 要编码的数据
 * @return string 编码后的字符串
 */
function b64_Encode($input) {
    return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}

/**
 * b64_Decode()将base64编码的数据解码
 * @param string $input 要解码的字符串
 * @return string 解码后的原始数据
 */
function b64_Decode($input) {
    $remainder = strlen($input) % 4;
    if ($remainder) {
        $addlen = 4 - $remainder;
        $input .= str_repeat('=', $addlen);
    }
    return base64_decode(strtr($input, '-_', '+/'));
}

/**
 * _sha256_uniqid() 生成uniqid随机识别码后使用sha256加密为64位代码
 * @return string 返回64位唯一识别码
 */
function _sha256_uniqid() {
    return _sha256(uniqid(rand(), true), false);
}

/**
 * _sha1_uniqid() 生成uniqid随机识别码后使用sha1加密为40位代码
 * @param 无参数
 * @return string 返回40位唯一识别码
 */
function _sha1_uniqid() {
    return sha1(uniqid(rand(), true), false);
}

/**
 * _sha1_uniqid() 生成uniqid随机识别码后使用sha1加密为40位代码
 * @param 无参数
 * @return string 返回40位唯一识别码
 */
// function _sha1_uniqid()
// {
//     return sha1(uniqid(rand(), true));
// }


/**
 * _ran4n 生成一个随机4位数
 * @return int 
 */
function _ran4n() {
    return rand(1000, 9999);
}

/**
 * _ran6n 生成一个随机6位数
 * @return int
 */
function _ran6n() {
    return rand(100000, 999999);
}

/**
 * _ran7n 生成一个随机6位数，并加上一位固定前缀
 * @return int
 */
function _ran7n($prefix = 9) {
    if (strlen($prefix) != 1) {
        $prefix = '9';
    }
    return $prefix . rand(100000, 999999);
}

/**
 * _pageN() 计算分页各个使用数字，要在页头运行 _pageN()，页尾运行 _paging()
 * @param string $_size 
 * @param int $total_Row
 */
function _pageN($_size, $total_Row) {
    //将里面所有变量做成全局，使函数外部可以访问
    global $_page, $_pagesize, $_pagenum, $_pageabsolute, $_total_num;
    //分页功能start
    if (isset($_GET['page'])) {
        $_page = $_GET['page'];
        if (empty($_page) || $_page <= 0 || !is_numeric($_page)) {
            $_page = 1;
        } else {
            $_page = intval($_page);
        }
    } else {
        $_page = 1;
    }
    $_pagesize = $_size;
    //数据总条数
    $_total_num = $total_Row;
    if ($_total_num == 0) {
        $_pageabsolute = 1;
    } else {
        $_pageabsolute = ceil($_total_num / $_pagesize);
    }
    if ($_page > $_pageabsolute) {
        $_page = $_pageabsolute;
    }
    $_pagenum = intval(($_page - 1) * $_pagesize);
    //分页功能end
}

/**
 * _page() 计算分页各个使用数字，要在页头运行 _page()，页尾运行 _paging()
 * @param string $_total_num
 * @param int $_size
 */
function _page($_total_num, $_size) {
    //将里面所有变量做成全局，使函数外部可以访问
    global $_page, $_pagesize, $_pagenum, $_pageabsolute, $_total_num;
    //分页功能start
    if (isset($_GET['page'])) {
        $_page = $_GET['page'];
        if (empty($_page) || $_page <= 0 || !is_numeric($_page)) {
            $_page = 1;
        } else {
            $_page = intval($_page);
        }
    } else {
        $_page = 1;
    }
    $_pagesize = $_size;
    //数据总条数
    if ($_total_num == 0) {
        $_pageabsolute = 1;
    } else {
        $_pageabsolute = ceil($_total_num / $_pagesize);
    }
    if ($_page > $_pageabsolute) {
        $_page = $_pageabsolute;
    }
    $_pagenum = intval(($_page - 1) * $_pagesize);
    //分页功能end
}

/**
 * _paging() 分页函数，要在页头运行 _page()，页尾运行 _paging()
 * @param int $_type  1为数字分页，2为文本分页
 * @return void 无返回，直接输出显示分页
 */
function _paging($_type) {
    global $_page, $_pageabsolute, $_total_num, $_pageid;
    if ($_type == 1) {
        echo '<div id="page_num">';
        echo '<ul>';
        for ($i = 1; $i <= $_pageabsolute; $i++) {
            if ($_page == $i) {
                echo '<li><a href="' . $_SERVER['SCRIPT_NAME'] . '?' . $_pageid . 'page=' . $i . '" class="selected">' . $i . '</a></li>';
            } else {
                echo '<li><a href="' . $_SERVER['SCRIPT_NAME'] . '?' . $_pageid . 'page=' . $i . '">' . $i . '</a></li>';
            }
            echo "\n";
        }
        echo '</ul>';
        echo '</div>';
    } else {
        echo '<div id="page_text">';
        echo '<ul>';
        echo '<li>共 ' . $_total_num . ' 条 / <span style="color:#0066ff;">' . $_pageabsolute . '</span> 页</li>';
        echo '<li>第<strong style="color:#ff3300;"> ' . $_page . ' </strong>页';
        //echo '<li>共 ' . $_pageabsolute . '页</li>';
        if ($_page == 1) {
            echo '<li>首页</li>';
            echo '<li>上一页</li>';
        } else {
            echo '<li><a href="' . $_SERVER['SCRIPT_NAME'] . '?' . $_pageid . 'page=1">首页</a></li>';
            echo '<li><a href="' . $_SERVER['SCRIPT_NAME'] . '?' . $_pageid . 'page=' . ($_page - 1) . '">上一页</a></li>';
        }
        if ($_page == $_pageabsolute) {
            echo '<li>下一页</li>';
            echo '<li>尾页</li>';
        } else {
            echo '<li><a href="' . $_SERVER['SCRIPT_NAME'] . '?' . $_pageid . 'page=' . ($_page + 1) . '">下一页</a></li>';
            echo '<li><a href="' . $_SERVER['SCRIPT_NAME'] . '?' . $_pageid . 'page=' . $_pageabsolute . '">尾页</a></li>';
        }
        echo '</ul>';
        echo '</div>';
    }
}

/**
 * _paging2() 分页函数，要在页头运行 _page()，页尾运行 _paging2()
 * @param int $_url 1为数字分页，2为文本分页
 * @return void 无返回，直接输出显示分页
 */
function _paging2($_url) {
    global $_page, $_pageabsolute, $_total_num, $_pageid;
        echo '<div id="page_text">';
        echo '<ul>';
        echo '<li>共 ' . $_total_num . ' 条 / <span style="color:#0066ff;">' . $_pageabsolute . '</span> 页</li>';
        echo '<li>第<strong style="color:#ff3300;"> ' . $_page . ' </strong>页';
        //echo '<li>共 ' . $_pageabsolute . '页</li>';
        if ($_page == 1) {
            echo '<li>首页</li>';
            echo '<li>上一页</li>';
        } else {
            echo '<li><a href="' . $_url . '&' . $_pageid . 'page=1">首页</a></li>';
            echo '<li><a href="' . $_url . '&' . $_pageid . 'page=' . ($_page - 1) . '">上一页</a></li>';
        }
        if ($_page == $_pageabsolute) {
            echo '<li>下一页</li>';
            echo '<li>尾页</li>';
        } else {
            echo '<li><a href="' . $_url . '&' . $_pageid . 'page=' . ($_page + 1) . '">下一页</a></li>';
            echo '<li><a href="' . $_url . '&' . $_pageid . 'page=' . $_pageabsolute . '">尾页</a></li>';
        }
        echo '</ul>';
        echo '</div>';
}

/**
 * _runtime() 获取当前Unix时间戳的微秒数，页面尾部执行结果-页面头部执行结果=页面执行耗时
 * @return float 表示返回出来的是一个浮点型数字
 */
function _runtime() {
    $_mtime = explode(' ', microtime());
    return $_mtime[1] + $_mtime[0];
}

/**
 * _unsetcookies() 清除登录状态的cookies
 * @param string $_gotourl 如果存在就跳转
 * @return null 清除后无动作或跳转
 */
function _unsetcookies($_gotourl) {
    setcookie('cookMerSignInfo', '', time() - 1, "/");
    if (!empty($_gotourl)) {
        header('location:' . $_gotourl);
    }
}

/**
 * dir_copy 文件夹文件拷贝
 * @param string $src 来源文件夹
 * @param string $dst 目的地文件夹
 * @return boolean 复制成功返回true，失败返回false
 */
function dir_copy($src = '', $dst = '') {
    //如果为空就终止
    if (empty($src) || empty($dst)) {
        return false;
    }
    //如果目录文件夹存在就终止
    if (is_dir($dst)) {
        return false;
    }
    $dir = opendir($src);
    dir_mkdir($dst);
    while (false !== ($file = readdir($dir))) {
        if (($file != '.') && ($file != '..')) {
            if (is_dir($src . '/' . $file)) {
                dir_copy($src . '/' . $file, $dst . '/' . $file);
            } else {
                copy($src . '/' . $file, $dst . '/' . $file);
            }
        }
    }
    closedir($dir);
    return true;
}

/**
 * dir_mkdir 创建文件夹
 * @param string $path 文件夹路径
 * @param int $mode 访问权限
 * @param bool $recursive 是否递归创建
 * @return boolean 成功返回true，失败返回false
 */
function dir_mkdir($path = '', $mode = 0777, $recursive = true) {
    // clearstatcache() 函数清除文件状态缓存。PHP 会缓存某些函数的返回信息，以便提供更高的性能。但是有时候，比如在一个脚本中多次检查同一个文件，而该文件在此脚本执行期间有被删除或修改的危险时，你需要清除文件状态缓存，以便获得正确的结果。
    clearstatcache();
    if (!is_dir($path)) {
        mkdir($path, $mode, $recursive);
        return chmod($path, $mode); // 改变文件模式 0777: 八进制数，正确的 mode 值，成功返回true，失败返回false。
    }
    return true;
}


/**
 * chk_file_exits 检查文件是否存在
 * @param string $file 文件路径
 * @return boolean 成功返回true，失败返回false
 */
function chk_file_exits($file) {
    // is_scalar()函数用于检测变量是否是一个标量（标量变量是指包含了integer、float、string或boolean的变量，而array、object和resource则不是标量）
    if (!is_scalar($file)) {
        return false;
    }
    $file = (string)$file;
    // is_file判断给定文件名是否为一个正常的文件。 is_readable()函数检查指定的文件是否可读。
    if (!is_file($file) || !is_readable($file)) {
        return false;
    }
    return true;
}

/**
 * del_target_file 删除指定文件
 * @param string $file 文件路径
 * @return boolean 成功返回true，失败返回false
 */
function del_target_file($file) {
    if (file_exists($file)) {
        // echo "上传的文件是存在的\n";
        $res = unlink($file); // 函数用于删除文件
        if ($res) {
            // echo '删除文件成功';
            return true;
        } else {
            // echo '删除文件失败';
            return false;
        }
    } else {
        return false;
    }
}

/**
 * del_folder_in_all 删除指定文件夹下所有 子文件夹及文件，不包含目录本身，目录必须以/结尾
 * @param string $path 文件路径
 * @return boolean 成功返回true，失败返回false
 */
function del_folder_in_all($path) {
    $backres = false;
    //如果是目录则继续
    if (is_dir($path)) {
        //扫描一个文件夹内的所有文件夹和文件并返回数组
        $p = scandir($path);
        foreach ($p as $val) {
            //排除目录中的.和..
            if ($val != "." && $val != "..") {
                //如果是目录则递归子目录，继续操作
                if (is_dir($path . $val)) {
                    //子目录中操作删除文件夹和文件
                    del_folder_in_all($path . $val . '/');
                    //目录清空后删除空文件夹
                    @rmdir($path . $val . '/');
                    $backres = true;
                } else {
                    //如果是文件直接删除
                    unlink($path . $val);
                    $backres = true;
                }
            }
        }
    }
    return $backres;
}


/**
 * gen_str()生成指定长度，的随机的数字英文混合字符串
 * @param int $length 生成多少位字符
 * @param int $method 可定义随机码组合方式
 * return string
 */
function gen_str($length, $method = 0) {
    $lower_str = 'abcdefghijklmnopqrstuvwxyz';
    $upper_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $num_str = '0123456789';
    $str_str = '';
    switch ($method) {
        case 1:
            $str_str = $num_str; //纯数字
            break;
        case 2:
            $str_str = $lower_str; //纯字母小写
            break;
        case 3:
            $str_str = $upper_str; //纯字母大写
            break;
        case 4:
            $str_str = $lower_str . $num_str; //字母(小写)数字
            break;
        case 5:
            $str_str = $upper_str . $num_str; //字母(大写)数字
            break;
        case 6:
            $str_str = $lower_str . $upper_str; //字母(小大写)
            break;
        default:
            $str_str = $lower_str . $upper_str . $num_str; //默认：大写字母+小写字母+数字
            break;
    }
    $len = strlen($str_str) - 1;
    $rand_str = '';
    for ($i = 0; $i < $length; $i++) {
        $num = mt_rand(0, $len);
        $rand_str .= $str_str[$num];
    }
    return $rand_str;
}

// /**
//  * encrypt_sign_str($str)编码并加密以URL传值或写Cookie的字符串
//  * @param string $str 要加密的字符，格式：{"userid":"103","username":"dream","valid_code":"94d410b2458d2f","dmf":"192.168.3.13","expt":"1644282355"}
//  * @return string 编码后的字符，格式: a.b.c
//  */
// function encrypt_sign_str($str)
// {
//     //第1位的数据base64加密
//     $info_b64str = b64_Encode($str);
//     //第2位的数据加密为安全验证字符串，用于取得真实数据后再对比
//     $sign_str = strtoupper(hash("sha256", $str . "DreamUrlSecret"));
//     //第3位的安全验证使用的随机字符
//     $rand_str = uniqid(rand(), false);
//     //第3位的随机字符使用_sha256加密成64位字符，用于随机插入到第1位的字符串中
//     //在decrypt_json_str解密中要将第3位_sha256加密后再替换掉第1位中的字符串
//     $encrypt_rand_str = _sha256($rand_str, false);
//     //将64位字符，随机插入到加密的使用数据中
//     $info_mixstr = rand_in_str($info_b64str, $encrypt_rand_str, 'utf-8');
//     //组合成 信息+秘钥+随机字符的长串
//     $str_all = $info_mixstr . "." . $sign_str . "." . $rand_str;
//     //echo rand_in_str($info_b64str, $rand_str, 'utf-8');
//     //echo '<br>';
//     return $str_all;
// }

// /**
//  * decrypt_json_str($str)解码以URL传值或写Cookie的字符串
//  * @param string $str 要解码的字符，格式: a.b.c
//  * @return string 解码成功返回Json数据，失败返回false
//  */
// function decrypt_json_str($str)
// {
//     $tokens = explode('.', $str);
//     if (count($tokens) != 3) {
//         return false;
//     }
//     list($info_mixstr, $sign_str, $rand_str) = $tokens;
//     //先将$rand_str加密后再替换掉
//     $encrypt_rand_str = _sha256($rand_str, false);
//     //将含有64位字符的串替换，这相当于其它人获取了字符串后使用base64解码的二次安全处理
//     $info_b64str = str_replace($encrypt_rand_str, "", $info_mixstr);
//     //echo $info_b64str;
//     //使用base64解码，得到json字符串
//     $get_info_str = b64_Decode($info_b64str);
//     //将Json格式转为数组，得到原始数据。
//     $original_arr = json_decode($get_info_str, JSON_OBJECT_AS_ARRAY);
//     //将解码后的json字符串和秘钥一起加密后，再和获取的第2位字符串进行对比
//     $newsign = strtoupper(hash("sha256", $get_info_str . "DreamUrlSecret"));
//     //输出前后2次秘钥对比
//     if ($newsign != $sign_str) {
//         return false;
//     }
//     //验证过期时间
//     if (isset($original_arr['expt']) && $original_arr['expt'] < time()) {
//         return false;
//     }
//     //验证来源和当前域名是否相同
//     if (isset($original_arr['dmf']) && $original_arr['dmf'] != $_SERVER["SERVER_NAME"]) {
//         return false;
//     }
//     //返回解码后的array原始数据
//     return $original_arr;
// }

// /**
//  * rand_in_str 向一个字符串随机位置插入一个字符串
//  * @param string $oldstr 老字符串
//  * @param string $instr 插入的字符串
//  * @param string $encoding 字符串编码
//  * @return string 新字符串
//  */
// function rand_in_str($oldstr, $instr, $encoding)
// {
//     //计算长度
//     $len = mb_strlen($oldstr, $encoding);
//     //生成随机位置数字
//     $insert_point = mt_rand(1, $len - 1);
//     //插入位置前面的字符串
//     $pre_str = mb_substr($oldstr, 0, $insert_point, $encoding);
//     //插入位置后面的字符串
//     $after_str = mb_substr($oldstr, $insert_point, $len - $insert_point, $encoding);
//     //链接前面+指定字符+后面的字符串
//     $newstr = $pre_str . $instr . $after_str;
//     return $newstr;
// }

// /**
//  * insert_to_str 向一个字符串随机插入一个字符串
//  * insert_to_str($oldstr, 'abc', 6, 'utf-8') 在第6位后面添加abc
//  * @param string $oldstr 原始字符串
//  * @param string $instr 插入的字符串
//  * @param string $insert_point 要插入的字符串的位置
//  * @param string $encoding 字符串编码
//  * @return string 新字符串
//  */
// function insert_to_str($oldstr, $instr, $insert_point, $encoding)
// {
//     //计算长度
//     $len = mb_strlen($oldstr, $encoding);
//     //插入位置前面的字符串
//     $pre_str = mb_substr($oldstr, 0, $insert_point, $encoding);
//     //插入位置后面的字符串
//     $after_str = mb_substr($oldstr, $insert_point, $len - $insert_point, $encoding);
//     //链接前面+指定字符+后面的字符串
//     $newstr = $pre_str . $instr . $after_str;
//     return $newstr;
// }



// /**
//  * _check_uniqid() 可以通过唯一标识符来防止恶意注册，伪装表单跨站攻击等
//  * @param string $_first_uniqid 表单中的随机标识符
//  * @param string $_session_uniqid 写入Session中的随机标识符
//  * @return string $_first_uniqid 对比成功后返回的标识符
//  */
// function _check_uniqid($_first_uniqid, $_session_uniqid, $_gotourl)
// {
//     if (strlen($_first_uniqid) != 40 || $_first_uniqid != $_session_uniqid) {
//         _alert_goto('来源无效', $_gotourl);
//     }
//     return $_first_uniqid;
// }

// /**
//  * _login_state() 登录状态验证
//  */
// function _login_state()
// {
//     if (isset($_COOKIE['username']) && isset($_COOKIE['ckuniqid']) && ($_COOKIE['loginresult'] == 9)) {
//         _alert_back('登录状态无法进行本操作');
//     }
// }

// /**
//  * _check_string() 为提交字符添加addslashes()转义
//  * @param string $_string 验证字符
//  * @return string $_string 转义后的字符
//  */
// function _check_string($_string)
// {
//     // get_magic_quotes_gpc() 如果开启状态，那么就不需要转义（*PHP6中删除了magic_quotes_gpc这个选项）
//     // if (!GPC) {
//         //echo "需要转义";
//         return addslashes($_string);
//     // } else {
//     //     //echo "不需要转义";
//     //     return $_string;
//     // }
// }

// /**
//  * _uniqid()判断唯一标识符是否异常
//  * @param $_string1
//  * @param $_string2
//  */
// function _uniqid($_string1, $_string2, $_tipstext = '对比不通过！')
// {
//     if ($_string1 != $_string2) {
//         _alert_back($_tipstext);
//     }
// }

// /**
//  * encrypt_sha256() 对字符串进行sha256加密
//  * @param string $str 要加密的字符
//  * @return string 加密后的64位代码
//  */
// function encrypt_sha256($str = '')
// {
//     return hash("sha256", $str);
// }


// /**
//  * _session_destroy() 销毁指定session，执行并跳转才会生效
//  */
// function _session_destroy()
// {
//     //销毁指定 Session，先判断后删除，验证码Session清除，防止返回页面后二次使用，执行后立即生效
//     if (isset($_SESSION['code'])) {
//         unset($_SESSION['code']);
//     }
//     if (isset($_SESSION['uniqid'])) {
//         unset($_SESSION['uniqid']);
//     }
// }

// /**
//  * _session_all_destroy() 销毁所有session，执行并跳转才会生效
//  */
// function _session_all_destroy()
// {
//     if (session_start()) {
//         session_destroy();
//     }
// }

?>